﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Data;
using System.Data.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Net.Mail;
using System.ComponentModel;
using PRT;
using Asterisk.NET.Manager;
using Asterisk.NET.Manager.Action;
using Asterisk.NET.Manager.Response;
using Asterisk.NET.FastAGI;
using Asterisk.NET.Manager.Event;
using System.Threading;
using System.Web.Security;

public partial class incoming : System.Web.UI.Page
{
    const string ASTERISK_HOST = "s131559x.trixbox.fonality.com";
    const int ASTERISK_PORT = 5038;
    const string ASTERISK_LOGINNAME = "remote_mgr";
    const string ASTERISK_LOGINPWD = "0chanc3yo";
    const int TIMEOUT = 10000;
    string CID, DID, channel, callUniqueID;

    ManagerConnection manager = new ManagerConnection(ASTERISK_HOST, ASTERISK_PORT, ASTERISK_LOGINNAME, ASTERISK_LOGINPWD);
    AnsweringServiceDataContext db = new AnsweringServiceDataContext();

    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            ViewState.Add("Ext", Request.QueryString["ext"]);

            try
            {
                manager.Login();	// Login only (fast)

                if (Session["MAC"] == null)
                {
                    ExtensionStateAction extStateAction = new ExtensionStateAction();
                    extStateAction.Exten = ViewState["Ext"].ToString();
                    ExtensionStateResponse extStateResponse = (ExtensionStateResponse)manager.SendAction(extStateAction, TIMEOUT);
                    Session["MAC"] = extStateResponse.Hint;
                }
                
                CommandResponse showChannels = (CommandResponse)manager.SendAction(new CommandAction("show channels concise"), TIMEOUT);
                string watchFor = (string)Session["MAC"];
                foreach (string result in showChannels.Result)
                {
                    Channel channel = new Channel(result);
                    if (channel.Name.StartsWith(watchFor))
                    {
                        if (watchFor.StartsWith("SIP"))
                            watchFor = channel.Bridged.Remove(channel.Bridged.Length - 1) + "1";
                        else
                        {
                            ViewState.Add("CID", channel.CallerID);
                            int beg = channel.Bridged.IndexOf("s@Q") + 3, end = channel.Bridged.IndexOf('-');
                            ViewState.Add("DID", channel.Bridged.Substring(beg, end - beg));
                            break;
                        }
                    }
                }
            }
            catch (ManagerException ex)
            {
                manager.Logoff();
                return;
            }
        }
    }

    protected void PhoneLink_Click(object sender, CommandEventArgs e)
    {
        try
        {
            manager.Login();	// Login only (fast)
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call")+12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }
            
            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = myChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = "*2" + e.CommandName;
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            if (Request.QueryString.HasKeys())
            {
                //if (Request.QueryString["CID"] != "")
                //    ViewState.Add("CID", Request.QueryString["CID"].Replace("-", ""));
                //if (Request.QueryString["DID"] != "")
                //    ViewState.Add("DID", Request.QueryString["DID"].Replace("-", ""));
                //if (Request.QueryString["ext"] != "")
                //    ViewState.Add("Ext", Request.QueryString["ext"]);

                try
                {
                    Client client = db.Clients.Single(c => c.ClientID == db.Numbers.Single(n => n.Number1 == ViewState["DID"] && n.DID == true).ClientID);
                    loadPageItems(client);
                    //mpTweener.Show();
                    btTakeCall_Click();
                }
                catch (Exception ex)
                {
                }
            }
        }
    }

    protected void loadPageItems(Client client)
    {
        ViewState.Add("Extension",client.Extension);
        lbTweenerGreeting.Text = client.Greeting;
        lbTweenerCallerInfo.Text = String.Format("{0:(###)###-####}", ViewState["CID"]);
        lbTweenerClientInfo.Text = client.Name + "(" + client.Number + ")";

        lbCallerInfo.Text = String.Format("{0:(###)###-####}", ViewState["CID"]);
        lbClientInfo.Text = client.Name + "(" + client.Number + ")";
        int numMessages = (from m in db.Messages
                           where m.Call.Event.ClientID == client.ClientID && m.Active == true
                           select m).Count();
        if (numMessages > 0)
            lkClientMessages.Text = numMessages.ToString() + " messages";
        lkClientMessages.NavigateUrl = "client.aspx?ID=" + client.ClientID;
        lbGreeting.Text = client.Greeting;
        lbScratchpad.Text = client.Scratchpad;
        tbEditScratchpad.Text = client.Scratchpad;
        lbInstructions.Text = client.Instructions;
        tbCallerNumber.Text = ViewState["CID"].ToString();
    }

    protected void btTakeCall_Click()
    //protected void btTakeCall_Click(object sender, EventArgs e)
    {
        Dictionary<string, OpenCall> openCalls = new Dictionary<string, OpenCall>();
        if (Application["OpenCalls"] != null)
            openCalls = (Dictionary<string, OpenCall>)Application["OpenCalls"];

            int clientID = 0;
            int callID = 0;

            if (ViewState["CID"] != null && ViewState["DID"] != null)
            {
                string key = ViewState["CID"] + "-" + ViewState["DID"];
                //Check to see if application variable exists for this caller
                if (openCalls.ContainsKey(key))
                {
                    OpenCall openCall = openCalls[key];
                    
                    //Populate text boxes with Application State Data
                    tbCallerName.Text = openCall.CallerName;
                    tbCallerNumber.Text = openCall.CallerNumber;
                    tbCallerAddress.Text = openCall.CallerAddress;
                    tbMessage.Text = openCall.Message;
                    
                    //assign callID and clientID
                    callID = openCall.CallID;
                    Call existingCall = db.Calls.Single(c => c.CallID == callID);
                    clientID = existingCall.Event.ClientID;
                }
                else
                {
                    //Insert new Event and Call records and return CallID
                    List<IncomingCallResult> IncomingCall = db.IncomingCall((string)ViewState["CID"], (string)ViewState["DID"]).ToList();
                    foreach (IncomingCallResult result in IncomingCall)
                    {
                        callID = result.CallID.Value;
                        clientID = result.ClientID.Value;
                    }
                    openCalls.Add(key, new OpenCall((string)ViewState["CID"], (string)ViewState["DID"], callID)); //Creates application variable for current call
                    Application["OpenCalls"] = openCalls;                
                }

                //Assign Viewstate and Hidden Field variables for other page functions
                ViewState.Add("CallID", callID);
                ViewState.Add("ClientID", clientID);
                hfCallID.Value = callID.ToString();

                //Get Call and Client table rows
                Call call = db.Calls.Single(c => c.CallID == callID);
                Client client = db.Clients.Single(c => c.ClientID == call.Event.ClientID);
                
                //Set page title
                this.Title = client.Name + "(" + client.Number + ")";

                //Set FollowUp indicator
                //cbFollowUp.Checked = call.Event.FollowUp.Value;

                //Set Specific Instructions
                var specificInstructions = from specInst in db.SpecificInstructions
                                           where specInst.ClientID == client.ClientID
                                           select specInst;
                ddSpecificInstructions.Items.Clear();
                if (specificInstructions.Count() > 0)
                {
                    ddSpecificInstructions.Visible = true;
                    lbSpecificInstructions.Text = specificInstructions.First().Instructions;
                }
                foreach (var instruction in specificInstructions)
                    ddSpecificInstructions.Items.Add(new ListItem(instruction.Description, instruction.SpecificInstructionID.ToString()));
                lkWebsite.Text = client.Website;
                lkWebsite.NavigateUrl = "http://" + client.Website;
                lkWebsite.Target = "_blank";

                //Set number links
                var phoneNumbers = from n in db.Numbers
                                   where n.NumberType.Phone == true && n.ClientID == clientID
                                   select n;

                lvNumbers.DataSource = phoneNumbers;
                lvNumbers.DataBind();

                //Populate Clients Emails
                var emails = from em in db.Emails
                             where em.ClientID == clientID
                             select em;

                foreach (var email in emails)
                    cbEmail.Items.Add(new ListItem(email.Address));

                //Populate clients messaging numbers
                var numbers = from n in db.Numbers
                              where n.ClientID == clientID
                              select n;
                foreach (var number in numbers)
                {
                    if (number.NumberType.FaxCapable == true)
                        cbFax.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
                    if (number.NumberType.SMSCapable == true)
                        cbSMS.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
                    if (number.NumberType.AlphaPageCapable == true)
                        cbAlpha.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
                    if (number.NumberType.NumericPageCapable == true)
                        cbNumeric.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
                }

                //Set up custom message fields
                var customFields = from fields in db.CustomFields
                                   where fields.ClientID == clientID
                                   select fields;
                foreach (var f in customFields)
                {
                    Label customLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$" + f.FieldColumn.FieldName + "_Label");
                    customLabel.Text = f.Name;
                    customLabel.Visible = true;
                    this.Master.FindControl("ctl00$ContentPlaceHolder1$" + f.FieldColumn.FieldName).Visible = true;
                }
            }
    }

    protected void btCancelCall_Click(object sender, EventArgs e)
    {
        try
        {
            manager.Login();	// Login only (fast)
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call")+12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }
            
            string ext = db.Clients.Single(c => c.ClientID == (int)ViewState["ClientID"]).Extension;

            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = theirChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = ext;
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }

        CloseWindow();

    }

    protected void btUpdateScratchpad_Click(object sender, EventArgs e)
    {
        var client = (from c in db.Clients
                      where c.ClientID == Convert.ToInt32(ViewState["ClientID"])
                      select c).First();
        client.Scratchpad = tbEditScratchpad.Text;
        db.SubmitChanges();
        lbScratchpad.Text = tbEditScratchpad.Text;
    }

    protected void ddSpecificInstructions_SelectedIndexChanged(object sender, EventArgs e)
    {
        lbSpecificInstructions.Text = (from si in db.SpecificInstructions where si.SpecificInstructionID == Convert.ToInt32(ddSpecificInstructions.SelectedValue) select si.Instructions).Single();
    }

    protected void btChooseAction_Command(object sender, CommandEventArgs e)
    {
        ActionTaken action = new ActionTaken();
        action.CallID = (int)ViewState["CallID"];
        action.ActionID = Convert.ToByte(e.CommandName);
        action.Timestamp = DateTime.Now;
        db.ActionTakens.InsertOnSubmit(action);
        db.SubmitChanges();
        lvActionsTaken.DataBind();
    }

    protected void btFollowUp_Click(object sender, EventArgs e)
    {
        FollowUp followUp = new FollowUp();
        followUp.CallID = (int)ViewState["CallID"];
        followUp.Reminder = DateTime.Now.AddMinutes(2);
        followUp.Interval = 2;
        db.FollowUps.InsertOnSubmit(followUp);
        db.SubmitChanges();

        //Event thisEvent = db.Calls.Single(c => c.CallID == (int)ViewState["CallID"]).Event;
        //cbFollowUp.Checked = true;
        //db.SubmitChanges();
    }

    protected void btSendMessage_Click(object sender, EventArgs e)
    {
        //Send emails
        MailAddressCollection to = new MailAddressCollection();
        foreach (ListItem cb in cbEmail.Items)
        {
            if (cb.Selected)
                to.Add(new MailAddress(cb.Value));
        }
        if (to.Count > 0)
            SendEmail(to, tbMessage.Text, getCustomFields());

        foreach (ListItem cb in cbSMS.Items)
        {
            if (cb.Selected)
            {
                //Goes one by one through the optional fields and determines if they are to be sent
                Number number = db.Numbers.Single(n => n.NumberID.ToString() == cb.Value);
                string message = "";
                if (tbCallerName.Text != "" && number.IncludeCallerName == true)
                    message += "Caller:" + tbCallerName.Text + " ";
                if (tbCallerNumber.Text != "" && number.IncludeCallerNumber == true)
                    message += "Number:" + tbCallerNumber.Text + " ";
                if (tbCallerAddress.Text != "" && number.IncludeCallerAddress == true)
                    message += "Address:" + tbCallerAddress.Text + " ";
                if (CustomText1.Text != "" && number.IncludeCustomText1 == true)
                    message += CustomText1_Label.Text + ": " + CustomText1.Text + " ";
                if (CustomText2.Text != "" && number.IncludeCustomText2 == true)
                    message += CustomText2_Label.Text + ": " + CustomText2.Text + " ";
                if (CustomText3.Text != "" && number.IncludeCustomText3 == true)
                    message += CustomText3_Label.Text + ": " + CustomText3.Text + " ";

                if (CustomNumeric1.Text != "" && number.IncludeCustomNumeric1 == true)
                    message += CustomNumeric1_Label.Text + ": " + CustomNumeric1.Text + " ";
                if (CustomNumeric2.Text != "" && number.IncludeCustomNumeric2 == true)
                    message += CustomNumeric2_Label.Text + ": " + CustomNumeric2.Text + " ";
                if (CustomNumeric3.Text != "" && number.IncludeCustomNumeric3 == true)
                    message += CustomNumeric3_Label.Text + ": " + CustomNumeric3.Text + " ";

                if (CustomDateTime1.Text != "" && number.IncludeCustomDateTime1 == true)
                    message += CustomDateTime1_Label.Text + ": " + CustomDateTime1.Text + " ";
                if (CustomDateTime2.Text != "" && number.IncludeCustomDateTime2 == true)
                    message += CustomDateTime2_Label.Text + ": " + CustomDateTime2.Text + " ";
                if (CustomDateTime3.Text != "" && number.IncludeCustomDateTime3 == true)
                    message += CustomDateTime3_Label.Text + ": " + CustomDateTime3.Text + " ";

                if (CustomBit1.Text != "" && number.IncludeCustomBit1 == true)
                    message += CustomBit1_Label.Text + ": " + CustomText1.Text + " ";
                if (CustomBit2.Text != "" && number.IncludeCustomBit2 == true)
                    message += CustomBit2_Label.Text + ": " + CustomText2.Text + " ";
                if (CustomBit3.Text != "" && number.IncludeCustomBit3 == true)
                    message += CustomBit3_Label.Text + ": " + CustomText3.Text + " ";

                if (tbMessage.Text != "")
                    message += " " + tbMessage.Text;

                sendSMS(number.Number1, number.Provider.SMSEmailAddress, message);
            }
        }
        foreach (ListItem cb in cbFax.Items)
        {
            if (cb.Selected)
            {
                //Code to Fax
            }
        }

        foreach (ListItem cb in cbAlpha.Items)
        {
            if (cb.Selected)
            {
                //Code to alpha page
            }
        }
        foreach (ListItem cb in cbNumeric.Items)
        {
            if (cb.Selected)
            {
                //Code to numeric page
            }
        }
        InsertMessage(false);
    }

    protected void btQueueMessage_Click(object sender, EventArgs e)
    {
        InsertMessage(true);
    }

    NameValueCollection getCustomFields()
    {
        NameValueCollection customFields = new NameValueCollection();
        for (int i = 1; i <= 3; i++)
        {
            Label textLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomText" + i + "_Label");
            TextBox textField = (TextBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomText" + i);
            if (textField.Text != "")
                customFields.Add(textLabel.Text, textField.Text);
            Label DateTimeLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomDateTime" + i + "_Label");
            TextBox DateTimeField = (TextBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomDateTime" + i);
            if (DateTimeField.Text != "")
                customFields.Add(DateTimeLabel.Text, DateTimeField.Text);
            Label numericLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomNumeric" + i + "_Label");
            TextBox numericField = (TextBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomNumeric" + i);
            if (numericField.Text != "")
                customFields.Add(numericLabel.Text, numericField.Text);
            Label bitLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomBit" + i + "_Label");
            CheckBox bitField = (CheckBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomBit" + i);
            if (bitField.Visible)
                customFields.Add(textLabel.Text, CheckedYesNo(bitField.Checked));
        }
        return customFields;
    }

    void InsertMessage(bool active)
    {
        //AnsweringServiceDataContext db = new AnsweringServiceDataContext();
        Message message = new Message();
        message.CallID = (int)ViewState["CallID"];
        message.Timestamp = DateTime.Now;
        message.Active = active;
        message.CallerName = tbCallerName.Text;
        message.CallerNumber = tbCallerNumber.Text;
        message.CallerAddress = tbCallerAddress.Text;
        message.Text = tbMessage.Text;
        if (CustomText1_Label.Text != "")
            message.CustomText1_Label = CustomText1_Label.Text;
        if (CustomText1.Text != "")
            message.CustomText1 = CustomText1.Text;
        if (CustomText2_Label.Text != "")
            message.CustomText1_Label = CustomText2_Label.Text;
        if (CustomText2.Text != "")
            message.CustomText2 = CustomText2.Text;
        if (CustomText3_Label.Text != "")
            message.CustomText3_Label = CustomText3_Label.Text;
        if (CustomText3.Text != "")
            message.CustomText3 = CustomText3.Text;

        if (CustomNumeric1_Label.Text != "")
            message.CustomNumeric1_Label = CustomNumeric1_Label.Text;
        if (CustomNumeric1.Text != "")
            message.CustomNumeric1 = Convert.ToDecimal(CustomNumeric1.Text);
        if (CustomNumeric2_Label.Text != "")
            message.CustomText1_Label = CustomNumeric2_Label.Text;
        if (CustomNumeric2.Text != "")
            message.CustomNumeric2 = Convert.ToDecimal(CustomNumeric2.Text);
        if (CustomNumeric3_Label.Text != "")
            message.CustomNumeric3_Label = CustomNumeric3_Label.Text;
        if (CustomNumeric3.Text != "")
            message.CustomNumeric3 = Convert.ToDecimal(CustomNumeric3.Text);

        if (CustomDateTime1_Label.Text != "")
            message.CustomDateTime1_Label = CustomDateTime1_Label.Text;
        if (CustomDateTime1.Text != "")
            message.CustomDateTime1 = Convert.ToDateTime(CustomDateTime1.Text);
        if (CustomDateTime2_Label.Text != "")
            message.CustomText1_Label = CustomDateTime2_Label.Text;
        if (CustomDateTime2.Text != "")
            message.CustomDateTime2 = Convert.ToDateTime(CustomDateTime2.Text);
        if (CustomDateTime3_Label.Text != "")
            message.CustomDateTime3_Label = CustomDateTime3_Label.Text;
        if (CustomDateTime3.Text != "")
            message.CustomDateTime3 = Convert.ToDateTime(CustomDateTime3.Text);

        if (CustomBit1_Label.Text != "")
            message.CustomBit1_Label = CustomBit1_Label.Text;
        if (CustomBit1.Text != "")
            message.CustomBit1 = CustomBit1.Checked;
        if (CustomBit2_Label.Text != "")
            message.CustomText1_Label = CustomBit2_Label.Text;
        if (CustomBit2.Text != "")
            message.CustomBit2 = CustomBit2.Checked;
        if (CustomBit3_Label.Text != "")
            message.CustomBit3_Label = CustomBit3_Label.Text;
        if (CustomBit3.Text != "")
            message.CustomBit3 = CustomBit3.Checked;
              
        db.Messages.InsertOnSubmit(message);
        db.SubmitChanges();
    }

    static string sendSMS(string number, string providerEmail, string message)
    {
        MailMessage objEmail = new MailMessage();
        objEmail.From = new MailAddress("messagecenter@bryan800.com");
        objEmail.Body = message;
        objEmail.To.Add(number + providerEmail);

        SmtpClient mailServer = new SmtpClient();
        try
        {
            mailServer.Send(objEmail);
            return ("Your Email has been sent sucessfully - Thank You");
        }
        catch (Exception exc)
        {
            return ("Send failure: " + exc.ToString());
        }
    }

    protected void btVoicemail_Click(object sender, EventArgs e)
    {
        //Push existing text into Application State
        string key = (string)ViewState["CID"] + "-" + (string)ViewState["DID"];
        Dictionary<string, OpenCall> openCalls = (Dictionary<string, OpenCall>)Application["OpenCalls"];
        OpenCall openCall = openCalls[key];
        openCall.CallerName = tbCallerName.Text;
        openCall.CallerNumber = tbCallerNumber.Text;
        openCall.CallerAddress = tbCallerAddress.Text;
        openCall.Message = tbMessage.Text;

        openCalls[key] = openCall;
        Application["OpenCalls"] = openCalls;
        
        //Send Command to place call to voicemail
        try
        {
            manager.Login();	// Login only (fast)
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call") + 12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }
            string ext = db.Clients.Single(c => c.ClientID == (int)ViewState["ClientID"]).Extension;
            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = theirChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = "*86"+ ext;
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }
    }

    protected void btPark_Click(object sender, EventArgs e)
    {
        //Push existing text into Application State
        string key = (string)ViewState["CID"] + "-" + (string)ViewState["DID"];
        Dictionary<string, OpenCall> openCalls = (Dictionary<string, OpenCall>)Application["OpenCalls"];
        OpenCall openCall = openCalls[key];
        openCall.CallerName = tbCallerName.Text;
        openCall.CallerNumber = tbCallerNumber.Text;
        openCall.CallerAddress = tbCallerAddress.Text;
        openCall.Message = tbMessage.Text;

        openCalls[key] = openCall;
        Application["OpenCalls"] = openCalls;
        
        //Send Command to place call back in queue
        try
        {
            manager.Login();	// Login only (fast)
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call") + 12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }

            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = theirChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = "9000";
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }

        CloseWindow();
    }

    protected void btCloseNoBill_Click(object sender, EventArgs e)
    {
        //Remove Application State Entry
        string key = (string)ViewState["CID"] + "-" + (string)ViewState["DID"];
        Dictionary<string, OpenCall> openCalls = (Dictionary<string, OpenCall>)Application["OpenCalls"];
        openCalls.Remove(key);
        Application["OpenCalls"] = openCalls;

        CloseWindow();
    }

    string CheckedYesNo(bool isChecked)
    {
        if (isChecked)
            return "Yes";
        else
            return "No";
    }

    static void SendEmail(MailAddressCollection to, string message, NameValueCollection customfields)
    {
        MailMessage mail = new MailMessage();

        mail.From = new MailAddress("messagecenter@bryan800.com");
        mail.Subject = "A message just arrived for you";
        mail.IsBodyHtml = true;
        string body = "<html><body>";
        body += (message + "<br /><br />");
        foreach (string key in customfields.AllKeys)
            body += (key + ": " + customfields[key] + "<br /><br />");
        body += "</body></html>";
        mail.Body = body;
        foreach (MailAddress adr in to)
            mail.To.Add(adr);

        SmtpClient mailServer = new SmtpClient();
        mailServer.Send(mail);
        /*
        object userState = mail;
        //wire up the event for when the Async send is completed
        mailServer.SendCompleted += new SendCompletedEventHandler(SmtpClient_OnCompleted);
        mailServer.SendAsync(mail, userState);*/
    }

    public static void SmtpClient_OnCompleted(object sender, AsyncCompletedEventArgs e)
    {
        //Get the Original MailMessage object
        MailMessage mail = (MailMessage)e.UserState;

        //write out the subject
        string subject = mail.Subject;

        if (e.Cancelled)
            Console.WriteLine("Send canceled for mail with subject [{0}].", subject);
        if (e.Error != null)
            Console.WriteLine("Error {1} occurred when sending mail [{0}] ", subject, e.Error.ToString());
        else
            Console.WriteLine("Message [{0}] sent.", subject);
    }

    protected void LinqDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {
        foreach (KeyValuePair<string, object> kvp in e.WhereParameters)
        {
            if (kvp.Value == null)
            {
                e.Cancel = true;
                return;
            }
        }
    }

    protected void CloseWindow()
    {
        string closeScript = "<script language=javascript>window.open('','_self','');window.close();</script>";
        if (!Page.ClientScript.IsStartupScriptRegistered("clientScript"))
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "clientScript", closeScript);
    }
    /*
    static void manager_IgnoreEvent(object sender, NewExtenEvent e)
    {
        // Ignore this event.
    }

    protected void dam_Events(object sender, ManagerEvent e)
    {
        if (ViewState["CID"] == null || ViewState["DID"] == null)
        {
            StatusEvent statusEvent = e as StatusEvent;
            if (statusEvent != null)
            {
                if (statusEvent.Channel != null && statusEvent.Channel == channel)
                {
                    ViewState["DID"] = statusEvent.CallerIdName.Replace("-", "");
                    ViewState["CID"] = statusEvent.CallerId.Replace("-","");
                }
            }
        }
    }
    /*
    
    static void dam_UserEvents(object sender, UserEvent e)
    {
        if (e is UserAgentLoginEvent)
        {
            Console.WriteLine("User Event - AgentLogin:"
                + "\n\tAgent\t\t" + ((UserAgentLoginEvent)e).Agent
                );
        }
        else
        {
            Console.WriteLine("User Event:"
                + "\n\tUserEventName\t\t" + e.UserEventName
                );
            foreach (System.Collections.Generic.KeyValuePair<string, string> pair in e.Attributes)
            {
                Console.WriteLine(String.Format("\t{0}\t{1}", pair.Key, pair.Value));
            }
        }
    }

    public class UserAgentLoginEvent : UserEvent
    {
        private string agent;
        public string Agent
        {
            get { return agent; }
            set { agent = value; }
        }

        public UserAgentLoginEvent(ManagerConnection source)
            : base(source)
        {
        }
    }
    */
}
